package com.chenyuxin.ilp.service.file.Impl;

import cn.hutool.core.bean.BeanUtil;
import com.aspose.slides.exceptions.SystemException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.chenyuxin.ilp.exception.BaseException;
import com.chenyuxin.ilp.mapper.file.FileFolderMapper;
import com.chenyuxin.ilp.mapper.file.FileMetaMapper;
import com.chenyuxin.ilp.mapper.file.FilePermissionMapper;
import com.chenyuxin.ilp.model.constant.FileSuccessConstant;
import com.chenyuxin.ilp.model.dto.file.CreateFolderDto;
import com.chenyuxin.ilp.model.dto.file.RenameFolderDto;
import com.chenyuxin.ilp.model.entity.file.FileFolder;
import com.chenyuxin.ilp.model.entity.file.FileMeta;
import com.chenyuxin.ilp.model.entity.file.FilePermission;
import com.chenyuxin.ilp.model.enums.db.file.PublicPermission;
import com.chenyuxin.ilp.model.enums.exception.ExceptionEnums;
import com.chenyuxin.ilp.model.enums.exception.FileExceptionEnums;
import com.chenyuxin.ilp.model.pojo.Result;
import com.chenyuxin.ilp.service.file.FileService;
import com.chenyuxin.ilp.service.file.FolderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class FolderServiceImpl implements FolderService {
    @Autowired
    private FileFolderMapper fileFolderMapper;
    @Autowired
    private FileMetaMapper fileMetaMapper;
    @Autowired
    private FileService fileService;
    @Autowired
    private FilePermissionMapper filePermissionMapper;

    // 添加文件夹
    @Override
    public Result createFolder(String userId, CreateFolderDto createFolderDto) {
        // 判断相同路径下是否有同名文件夹
        if(this.folderExist(createFolderDto.getParentId(),createFolderDto.getFolderName())){
            throw new BaseException(FileExceptionEnums.FOLDER_EXIST);
        }
        FileFolder fileFolder = BeanUtil.copyProperties(createFolderDto, FileFolder.class);
        fileFolder.setUserId(userId);
        fileFolder.setIsShare(PublicPermission.PRIVATE.getCode());
        fileFolder.setCreateTime(LocalDateTime.now());
        fileFolder.setIsOpen(0);
        fileFolder.setIsShare(0);
        fileFolderMapper.insert(fileFolder);
        return Result.ok(FileSuccessConstant.CREATE_FOLDER_SUCCESS,null);
    }
    // 删除文件夹
    @Transactional
    @Override
    public Result deleteFolder(String userId, Long folderId) {
        //1 查询所有子文件夹
        List<Long> folderIds =  fileFolderMapper.selectSonFolderId(userId,folderId);
        //2 删除所有子文件夹
        folderIds.add(folderId);
        LambdaQueryWrapper<FileFolder> folderWrapper = new LambdaQueryWrapper<>();
        folderWrapper.in(FileFolder::getId,folderIds);
        fileFolderMapper.delete(folderWrapper);
        //3 删除所有子文件夹权限
        LambdaQueryWrapper<FilePermission> filePermissionWrapper = new LambdaQueryWrapper<>();
        filePermissionWrapper.eq(FilePermission::getHostUserId,userId)
                .in(FilePermission::getFolderId,folderIds);
        filePermissionMapper.delete(filePermissionWrapper);
        //4 查询所有子文件
        LambdaQueryWrapper<FileMeta> fileWrapper = new LambdaQueryWrapper<>();
        fileWrapper.select(FileMeta::getId)
                .in(FileMeta::getParentId,folderIds)
                .eq(FileMeta::getUserId,userId)
                .eq(FileMeta::getIsDelete,0);
        List<Long> fileIds = fileMetaMapper.selectList(fileWrapper)
                .stream().map(FileMeta::getId)
                .collect(Collectors.toList());
        //5 删除所有子文件
        if (!fileIds.isEmpty()){
            fileService.deleteFileBatch(userId,fileIds);
        }
        return Result.ok(FileSuccessConstant.DELETE_FOLDER_SUCCESS,null);
    }
    // 查询用户根文件夹
    @Override
    public Result selectRootFolder(String userId) {
        LambdaQueryWrapper<FileFolder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FileFolder::getLevel,0)
                .eq(FileFolder::getUserId,userId);
        FileFolder fileFolder = fileFolderMapper.selectOne(wrapper);
        if(fileFolder==null){
            fileFolder = new FileFolder();
            fileFolder.setIsShare(0);
            fileFolder.setLevel(0);
            fileFolder.setUserId(userId);
            fileFolder.setCreateTime(LocalDateTime.now());
            fileFolderMapper.insert(fileFolder);
        }
        return Result.ok(fileFolder.getId());
    }
    // 重命名文件夹
    @Override
    public Result renameFolder(String userId, RenameFolderDto renameFolderDto) {
        //1 查询父文件夹
        FileFolder fileFolder = fileFolderMapper.selectById(renameFolderDto.getFolderId());
        if(fileFolder==null){
            throw new BaseException(ExceptionEnums.SYSTEM_ERROR);
        }
        //2 判断文件夹名称是否重复
        if(this.folderExist(fileFolder.getParentId(),renameFolderDto.getName())){
            throw new BaseException(FileExceptionEnums.FOLDER_NAME_SAME);
        }
        //3 文件夹重命名
        LambdaUpdateWrapper<FileFolder> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(FileFolder::getUserId,userId)
                .eq(FileFolder::getId,renameFolderDto.getFolderId())
                .set(FileFolder::getFolderName,renameFolderDto.getName());
        fileFolderMapper.update(wrapper);
        return Result.ok(FileSuccessConstant.RENAME_FOLDER_SUCCESS,null);
    }
    // 修改文件夹公开权限
    @Override
    public Result changeFolderOpen(Long folderId, Integer isOpen, String userId) {
        // 修改所有子文件子文件夹的权限
        List<Long> sonFolderIds = fileFolderMapper.selectSonFolderId(userId, folderId);
        for(Long id:sonFolderIds){
            LambdaUpdateWrapper<FileFolder> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(FileFolder::getId,id)
                    .eq(FileFolder::getUserId,userId)
                    .set(FileFolder::getIsOpen,isOpen);
            fileFolderMapper.update(wrapper);
        }
        // 修改所有子文件权限
        LambdaUpdateWrapper<FileMeta> fileWrapper = new LambdaUpdateWrapper<>();
        fileWrapper.eq(FileMeta::getUserId,userId)
                .eq(FileMeta::getIsDelete,0)
                .in(FileMeta::getParentId,sonFolderIds)
                .set(FileMeta::getIsOpen,isOpen);
        fileMetaMapper.update(fileWrapper);
        return Result.ok(FileSuccessConstant.UPDATE_FOLDER_AUTHORITY_SUCCESS,null);
    }

    // 判断文件是否重名
    private Boolean folderExist(Long parentId,String folderName){
        LambdaQueryWrapper<FileFolder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FileFolder::getFolderName,folderName)
                        .eq(FileFolder::getParentId,parentId);
        FileFolder fileFolder = fileFolderMapper.selectOne(wrapper);
        if(fileFolder==null){
            return false;
        }
        return true;
    }
}
